/*  Test Nyberg-Rueppel code for polynomial basis  */

#include <stdio.h>
#include "bigint.h"
#include "poly.h"
#include "eliptic.h"
#include "protocols.h"

extern FIELD2N poly_prime;
extern void sha_memory();
extern unsigned long random_seed;

main()
{
	FIELD2N			roots[3];
	EC_PARAMETER	Base;
	EC_KEYPAIR		Signer;
	SIGNATURE		signature;
	BIGINT			prime_order;
	POINT			temp;
	INDEX 			i, error;
	char			Message[1024];
	
/*	char string1[MAXSTRING] = "324518553658426701487448656461467"; /*N 109 */ 
	char string1[MAXSTRING] = "324518553658426723114957572335741"; /*N 111  */
/*	char string1[MAXSTRING] = "5192296858534827627896703833467507"; /*N 113  */
/*	char string1[MAXSTRING] = "680564733841876926932320129493409985129";*/ /*N~ 131 */
/*	char string1[MAXSTRING] = "5444517870735015415344659586094410599059"; /*N 134 (g^2 = g+1)	*/
/*	char string1[MAXSTRING] = "19822884620916109459140767798279811163792081";*/ /*N~ 148 GF(16) */
/*	char string1[MAXSTRING] = "91343852333181432387730573045979447452365303319";*/  /* N 158 */
/*	char string1[MAXSTRING] = "5846006549323611672814741753598448348329118574063"; */ /* 163 */ 

	random_seed = 0x9ef1b325;

	if (!irreducible(&poly_prime)) return(0);
	print_field("poly_prime = ", &poly_prime);
	
	if (error = init_poly_math())
	{
		printf("Can't initialize S matrix, row = %d\n", error);
		return(-1);
	}

/*  compute curve order from Koblitz data  */

	ascii_to_bigint(&string1, &prime_order);
	int_to_field( &prime_order, &Base.pnt_order);
	null( &Base.cofactor);
	Base.cofactor.e[NUMWORD] = 8;

	printf("create Base curve and point\n\n");

	Base.crv.form = 0;
	null(&Base.crv.a2);
	poly_gf8(&poly_prime, roots);
	copy( &roots[0], &Base.crv.a6);
	print_curve("Public curve", &Base.crv);
	
	rand_point(&temp, &Base.crv);
	poly_elptic_mul(&Base.cofactor, &temp, &Base.pnt, &Base.crv);
	print_point("Base point", &Base.pnt);

/*  create a secret key for testing. Note that secret key must be less than order.
	The standard implies that the field size which can be used is one bit less than
	the length of the public base point order.
*/

	poly_ECKGP( &Base, &Signer);
	print_field("Signer's secret key", &Signer.prvt_key);
	print_point("Signers public key", &Signer.pblc_key);
	
/*  create a message to be signed  */

	for (i=0; i<1024; i++) Message[i] = i;

/*  call Nyberg_Ruepple signature scheme  */

	poly_NR_Signature( Message, 1024, &Base, &Signer.prvt_key, &signature);
	print_field("first component of signature", &signature.c);
	print_field("second component of signature", &signature.d);

/*  verify message has not been tampered.  Need public curve parameters, signers
	public key, message, length of message, and order of public curve parameters
	as well as the signature. If there is a null response, message is not same as
	the orignal signed version.
*/
	error = poly_NR_Verify( Message, 1024, &Base, &Signer.pblc_key, &signature);
	if (error) printf("Message Verifies");
	else printf("Message fails!");
}